﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ExtremeEvents.Models;
using System.Web.Security;
using System.Net.Mail;
using System.Net;
using System.Data.Entity;
using System.Data.SqlClient;
namespace ExtremeEvents.Controllers
{
    public class AccountController : Controller
    {
        //
        // GET: /Contas/Login

        public ActionResult LogOn()
        {
            return View();
        }

        //
        // POST: /Contas/Login

        [HttpPost]
        public ActionResult LogOn(LoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.Login, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.Login, model.Relembrar_Me);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                       // return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Error_16: O login está incorreto.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Contas/Registar

        public ActionResult Register()
        {
            //Para popular a dropdownlist
            List<string> lista = new List<string>();
            lista.Add("Portugal");
            lista.Add("Outro");
            Utilizador utilizador = new Utilizador
                {
                    Paises = lista        
                };
            

            //envia o modelo preenchido com os países
            return View(utilizador);
        }

        //
        // POST: /Contas/Registar

        [HttpPost]
        public ActionResult Register(Utilizador model)
        {
            if (ModelState.IsValid)
            {
                //Para popular a dropdownlist
                List<string> lista = new List<string>();
                lista.Add("Portugal");
                lista.Add("Outro");
                model.Paises = lista;

                // Attempt to register the user
                // Cria o user do Membership 
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.Login, model.Password, model.Email, "pergunta", "resposta", true, null, out createStatus);
                
                // Objecto que vai conter os parametros do nosso user
                object[] param = new object[13];
                //Query sql para inserir o nosso user
                String sql = "";
                sql += "INSERT INTO [ext].[utilizador]";
                sql += " ([id_utilizador],[primeiro_nome],[ultimo_nome],[genero]";
                sql += ",[nif],[nome_organizacao],[morada],[numero]";
                sql += ",[codigo_postal],[concelho],[distrito],[freguesia],[pais])";
                sql += " Values({0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12})";
                param[0] = null;
                param[1] = model.Primeiro_Nome;
                param[2] = model.Ultimo_Nome;
                param[3] = model.Genero;
                param[4] = model.Nif;
                param[5] = model.Nome_Organizacao;
                param[6] = model.Morada;
                param[7] = model.Numero;
                param[8] = model.Codigo_Postal;
                param[9] = model.Concelho;
                param[10] = model.Distrito;
                param[11] = model.Freguesia;
                param[12] = model.Pais;
                
               
                if (createStatus == MembershipCreateStatus.Success)
                {
                    //Atribuir automaticamente o Role
                    Roles.AddUserToRole(model.Login,"Utilizador");
                    FormsAuthentication.SetAuthCookie(model.Login, false /* createPersistentCookie */);
                    //Retorna o user acabado de criar no Membership
                    MembershipUser user = Membership.GetUser(model.Primeiro_Nome); 
                    
                    ExtremeEventsIntity db = new ExtremeEventsIntity();
                    //Parametro de output para receber o id do user @key
                    var key = new SqlParameter
                    {
                        ParameterName = "key",
                        DbType = System.Data.DbType.String,
                        Size = 100,
                        Direction = System.Data.ParameterDirection.Output
                    };
                    //Parametro de input para aceder ao user @nome
                    var nome = new SqlParameter
                    {
                        ParameterName = "nome",
                        DbType = System.Data.DbType.String,
                        Size = 100,
                        Direction = System.Data.ParameterDirection.Input,
                        Value = model.Login
                    };
                    //query para selecionar o userId para o parametro @key através do @nome
                    db.Database.ExecuteSqlCommand("SELECT @key = UserId FROM dbo.aspnet_Users WHERE UserName = @nome",key, nome );
                    param[0] = key.SqlValue; 
                    //Query para inserir o nosso Utilizador
                    db.Database.ExecuteSqlCommand(sql, param);// model.Login, model.Primeiro_Nome, model.Ultimo_Nome, model.Email);

                    return RedirectToAction("LogOn", "Account");
                }

                else if (createStatus == MembershipCreateStatus.DuplicateUserName)
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                    ViewBag.erro = createStatus.ToString();
                }
                else if (createStatus == MembershipCreateStatus.DuplicateEmail )
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                    ViewBag.erro = createStatus.ToString();
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                    ViewBag.erro = createStatus.ToString();
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Conta/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Conta/MudaPassword

        [Authorize]
        public ActionResult ChangePassword()
        {
            return View();
        }

        //
        // POST: /Conta/MudaPassword

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(MudarPasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.Password_Antiga, model.Password_Nova);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "Error_17: A password está incorreta ou a password nova é inválida.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }


        //
        // GET: /Account/RecoverPAssword

        public ActionResult RecoverPassword()
        {
            return View();
        }

        //
        // POST: /Account/RecoverPAssword

        [HttpPost]
        public ActionResult RecoverPassword(PasswordRetrievalModel model)
        {
            if (ModelState.IsValid)
            {
                //Retorna uma collection de users que tenham o email inserido. 
                //Se a contagem for 0 volta para a view com mensagem de erro
                MembershipUserCollection email = Membership.FindUsersByEmail(model.email);
                if (email.Count == 0)
                {
                    ViewBag.erro = "Error_11: Não existe registo para o email escolhido!";
                    return View(model);
                }
                //Devolve o user através do email faz reset e envia a nova pass @newP ao user
                MembershipUser user = Membership.GetUser(Membership.GetUserNameByEmail(model.email));
                try
                {
                    if (user != null)
                    {
                        string newP = user.ResetPassword("resposta");
                        MailMessage mail = new MailMessage();
                        SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com", 587); //587
                        SmtpServer.Credentials = new NetworkCredential("extremeevents11@gmail.com", "Eventosmuitabons");
                        SmtpServer.EnableSsl = true;
                        mail.From = new MailAddress("extremeevents11@gmail.com");
                        mail.To.Add(model.email);
                        mail.Subject = "Recuperação password";
                        mail.Body += "Foi pedida uma password nova para a sua conta!\n";
                        mail.Body += "Nova password: " + newP;
                        mail.Body += "\nObrigado!";
                        SmtpServer.Send(mail);

                        return RedirectToAction("RecoverPasswordSucess");
                    }
                }
                catch (Exception e)
                {
                    ViewBag.erro = "Error_12: Ocorreu um erro a enviar o email! Por favor tente mais tarde!\n" + e.Message + "\n" + e.ToString();
                }
            }
            return View(model);
        }

        public ActionResult RecoverPasswordSucess()
        {
            return View();
        }

       #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "Error_01: O utilizador já existe. Por favor insira um nome diferente.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "Error_02: O utilizador para este email já existe. Por favor insira um e-mail diferente.";

                case MembershipCreateStatus.InvalidPassword:
                    return "Error_03: A password inserida é inválida. Por favor insira uma password válida.";

                case MembershipCreateStatus.InvalidEmail:
                    return "Error_04: O endereço de e-mail é inválido. Por favor corrija-o e tente de novo.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "Error_5: A resposta à password inserida é inválida. Por favor verifique-a e tente de novo.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "Error_6: A questão à password inserida é inválida. Por favor verifique-a e tente de novo.";

                case MembershipCreateStatus.InvalidUserName:
                    return "Error_7: O nome de utilizador é inválido. Por favor corrija-o e tente de novo.";

                case MembershipCreateStatus.ProviderError:
                    return "Error_8: Erro de autenticação. Por favor verifique os dados introduzidos e tente de novo. Se o problema persistir, contacte o administrador de sistema.";

                case MembershipCreateStatus.UserRejected:
                    return "Error_9: Erro na criação de utilizador. Por favor verifique os dados introduzidos e tente de novo. Se o problema persistir, contacte o administrador de sistema.";

                default:
                    return "Error_10: erro na criação de utilizador. Por favor verifique os dados introduzidos e tente de novo. Se o problema persistir, contacte o administrador de sistema.";
            }
        }
        #endregion
    }
}
